302 API Redirect Problem
If you make a request to a REST service and are not logged in, by default ASP .NET 5 Identity returns a 302 Redirect to login page. This is great if you are visiting the URL of a controller directly. If you make an Ajax request to a specific REST API and are not logged in however, you are also redirected to the login page and instead of the content of the API you will get the content of the login page itself. Probably without even noticing it right away.
So in instance of API calls I would prefer a 401 Unauthorized status code, e.g. $http requests using AngularJS. Here only the Ajax call itself gets redirected, but the URL of the browser remains the same. This means you won’t see that there is an “authentication problem” and you are not redirected to the login page.
The solution – 401 for API Calls
In the Startup.cs in method ConfigureServices provide a different logic for OnRedirectToLogin.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
services.Configure<IdentityOptions>(options => { options.Cookies.ApplicationCookie.LoginPath = new PathString("/"); options.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents() { OnRedirectToLogin = context => { if (context.Request.Path.Value.StartsWith("/api")) { context.Response.Clear(); context.Response.StatusCode = 401; return Task.FromResult(0); } context.Response.Redirect(context.RedirectUri); return Task.FromResult(0); } }; }); |
This is the simplest solution of all, by checking the request path for API calls. Of course you can also check the request header to see if it is an Ajax call.
By the way… this small piece of code took me quite a while to figure out. There are sooooo many outdated and wrong examples for this out there. I tried countless ones. They all compiled well, but the code never got executed.
NOT WORKING Examples:
1 2 3 4 5 |
services.AddCookieAuthentication(config => { config.LoginPath = "/Auth/Login"; ... }); |
1 2 3 4 5 6 7 8 9 10 |
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), Provider = new CookieAuthenticationProvider { } }); |
All code examples that have a Provider property are outdated.
Summary
This article demonstrates how to change the status code from 302 to 401 for calls to specific controllers. In a future article I will demonstrate how to intercept 401 status codes in Ajax calls within AngularJS and redirect the user to a login page.
A motivating discussion is definitely worth comment.
I think that you need to write more on this subject matter, it might not be a taboo
subject but usually folks don’t talk about these topics. To the
next! Cheers!!
Microsoft fixed it https://aspnet.uservoice.com/forums/147201-asp-net-web-api/suggestions/2856315-add-option-to-return-401-not-authorized-instead-of
Great solution thanks! Was struggling with this for a while as well.
This is not ASP.NET MVC5 it is ASP.NET CORE
For Web API 2,check the Startup_auth.cs entry for app.UseCookieAuthentication(…options…) If it contains options with LoginPath= new PathString(“/Account/Login”) comment this out or set it to null.
Dude! You save my life! Thanks!!!
Amazing info. Very useful….
Thank you Sebastian 🙂